/**
 * 文件内容替换和重命名脚本
 *
 * 该脚本用于在构建过程中对指定文件进行内容替换和文件名重命名操作，
 * 以适应不同环境和渠道的配置需求。
 *
 * 主要功能包括：
 * 1. 文件内容替换：
 *    - 根据配置识别需要替换内容的文件
 *    - 支持多环境配置（开发、测试、生产等）
 *    - 支持多渠道配置（不同产品渠道使用不同配置）
 *    - 自动匹配环境对应的替换规则
 *    - 执行文本内容的键值对替换
 *
 * 2. 文件重命名：
 *    - 根据配置对指定文件进行重命名
 *    - 自动复制文件内容到新文件名
 *    - 删除原始文件
 *    - 更新文件路径引用
 *
 * 3. 渠道化支持：
 *    - 支持为不同产品渠道生成特定配置文件
 *    - 为每个渠道创建独立的配置文件副本
 *    - 保持原始文件不变，生成渠道特定版本
 *
 * 工作流程：
 * - 在构建流程中自动执行替换任务
 * - 检查配置确定需要处理的文件
 * - 遍历新增和更新的文件列表
 * - 对匹配的文件执行内容替换操作
 * - 根据渠道配置生成对应的文件版本
 * - 执行文件重命名操作
 *
 * 配置支持：
 * - replaceFile: 需要内容替换的文件列表
 * - replaceNameFile: 需要重命名的文件映射关系
 * - replace: 替换规则配置，支持按环境和渠道分类
 * - productFlavors: 产品渠道配置
 *
 * 文件命名规则：
 * - 渠道文件命名格式: {原文件名}_{渠道名}.{扩展名}
 * - 配置文件命名格式: {文件名}Replace
 * - 渠道配置文件命名格式: {渠道名}_{文件名}Replace
 *
 * 适用场景：
 * - 多环境配置管理（开发/测试/生产环境）
 * - 多渠道发布（不同应用商店使用不同配置）
 * - 敏感信息替换（API密钥、服务器地址等）
 * - 本地化配置（不同地区使用不同设置）
 */
package com.script

import com.entity.PackPath
import com.utils.ScriptUtils.appConfig
import com.utils.ScriptUtils.contrastFile
import com.utils.ScriptUtils.script
import org.apache.logging.log4j.kotlin.logger

script.onReplace = ::replace

script.methodMap["_replaceContent"] = ::doReplaceContent

private fun replace() {

    logger.info("进入替换文件流程")

    val addFile = contrastFile.addFileList
    val updateFile = contrastFile.updateFileList

    val fileList = addFile + updateFile

    // 有替换文件配置的时候  启动
    if (appConfig.replaceFile.isNotEmpty()) {
        // 替换文件临时名字
        for (replaceName in appConfig.replaceFile) {
            // 有变更的文件
            fileList.forEach { file ->
                if (file.pathString.endsWith(replaceName)) {
                    replaceContent(file)
                }
            }
        }
    }

    // 执行替换文件名字操作
    if (appConfig.replaceNameFile.isNotEmpty()) {
        for ((key, value) in appConfig.replaceNameFile) {
            // 有变更的文件
            fileList.forEach { file ->
                val filePathStr = file.pathString
                if (filePathStr.endsWith(key)) {
                    val newFile = filePathStr.replace(key, value, false)
                    val desFile = PackPath(newFile)
                    logger.info("发现改名文件:$file --> $newFile")

                    file.copyTo(desFile)
                    file.deleteRecursively()

                    file.replacePath(newFile)

                }

            }

        }


    }

}

private fun replaceContent(file: PackPath) {
    val name = file.nameWithoutExtension
    logger.info("需要修改内容的文件 $name")

    // 获取替换文件对于的配置文件名字
    val fileNameScript = "${name}Replace"
    // 判断是否存在渠道
    if (appConfig.productFlavors.isNotEmpty()) {
        for (flavors in appConfig.productFlavors) {
            val newFileNameScript = "${flavors}_$fileNameScript"
            if (appConfig.replace.containsKey(newFileNameScript)) { // 如果存在配置 就执行一次替换
                logger.info("文件 $name 执行渠道配置替换处理")
                doReplaceContent(file, newFileNameScript, flavors)
//            } else {
//                logger.info("文件 $name 未发现渠道配置，执行默认配置替换处理")
//                doReplaceContent(file, fileNameScript, flavors)
            }
        }
    }
    // 最后处理正常环境的替换
    doReplaceContent(file, fileNameScript)

}

fun doReplaceContent(packPath: PackPath, fileNameScript: String, flavorsName: String? = null) {
    var file = packPath

    logger.info("替换文件配置名字=$fileNameScript")
    // 读取替换文件内容
    var configContext = file.readText()
    // 获取当前替换文件的配置文件信息
    val replaceScript = appConfig.replace[fileNameScript]!!
    // 获取指定环境的配置文件
    //print("replace 1 "..fileNameScript.." | "..YamlUtil.unpackScene)
    //print("replace 2 "..#replaceScript)
    var replaceData = mutableMapOf<String, String>()
    if (replaceScript.size > 1) {
        val runName = appConfig.runEnvironment().name
        replaceData = replaceScript[runName]!!
    } else if (replaceScript.size == 1) {
        replaceData = replaceScript.values.first()
    }

    // 执行替换
    for ((key, value) in replaceData) {
        //print("replace 3 "..replaceScript[i].."  -  "..replaceScript[i + 1])
        logger.info("${file.nameWithoutExtension} 执行替换内容: $key -> $value")
        configContext = configContext.replace(key, value)
    }

    //  保存新版本的配置
    if (flavorsName != null) {
        val fileName = "${file.nameWithoutExtension}_$flavorsName.${file.extension}"

        file = file.parent!!.resolve(fileName)
        // 做为新添加的文件写入
        val addFile = contrastFile.addFileList
        addFile.add(file)
    }
    val newScript = contrastFile.scriptFormat(configContext)
    file.writeText(newScript)

    logger.info("替换内容完成，保存替换文件 ${file.toAbsolutePath()}")

}